import socket
import threading
import time
'''
参考文献
https://blog.sina.com.cn/s/blog_75c55a1501011ujp.html
https://blog.csdn.net/m0_55987469/article/details/130267870
https://blog.csdn.net/qq_35029061/article/details/125869635?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-8-125869635-blog-138036641.235^v43^pc_blog_bottom_relevance_base4&spm=1001.2101.3001.4242.5&utm_relevant_index=11
'''


class TIce104Client:
    def __init__(self):
        self.ip = "192.168.8.10"
        self.port = 2404
        self.connected = False
        self.skt = None
        self.clientStatus = {
            "setTime":0 ,
            "status":0
        }
        self.sendBuf = []
        self.cmds={
            "start": bytearray([0x68,0x04,0x07,0,0,0 ]),
            "test":bytearray([0x68,0x04,0x43,0,0,0]),
            "testresp":bytearray([0x68,0x04,0x83,0,0,0]),
            "s": bytearray([0x68,0x04,0x01,0,0,0]),
        }
    def start(self):
        res = False
        try:
            tm = str(int(time.time()))
            print(f'start ic4104.{tm}')
            self.connectHost(self.ip , self.port)
            if self.isOpen():
                print(f"ice104 master is connected! [{self.ip}:{self.port}] ")

                startCmd = self.cmds['start']
                sendRes = self.skt.send(startCmd)
                print(sendRes, self.getBytesStr(startCmd))
                time.sleep(1)

                threadRec = threading.Thread(target=self.execRec , daemon=True)
                threadRec.start()
                threadLoop = threading.Thread(target=self.execLoop , daemon=True)
                threadLoop.start()
            else:
                print('connect 104 master faild')
        except Exception as er:
            print(er)
        return  res
    def stop(self):
        res = False
        try:
            tm = str(int(time.time()))
            print(f'stop ic4104.{tm}')
        except Exception as er:
            print(er)
        return  res
    def restart(self):
        res = False
        try:
            self.stop()
            threadRec = threading.Thread(target=self.exec , daemon=True)
            threadRec.start()

        except Exception as er:
            print(er)
        return  res
    def isOpen(self):
        res = False
        try:
            flag = (self.skt!=None) and self.connected
            res = flag
        except Exception as er:
            print(er)
        return  res
    def getBytesStr(self, bytes):
        res = [hex(x) for x in bytes]
        return  res
    def connectHost(self , host , port):
        try:
            client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            server_address = ( host , port)
            client_socket.connect(server_address)
            self.skt = client_socket
            self.connected = True

        except Exception as er:
            print(er)
            self.connected = False
        return  self.connected
    def close(self ):
        res = False
        try:
            pass
        except Exception as er:
            print(er)
        return  res

    def setClientStatus(self , status):
        try:
            self.clientStatus={
                "setTime":time.time() ,
                "status":status
            }
        except Exception as er:
            print(er)
        self.clientStatus = 0
    def exec(self):
        try:
            '''
            self.skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.skt.setblocking(True)
            server_address = ( self.ip , self.port)
            self.skt.connect(server_address)
            time.sleep(1)
            self.skt.close()
            time.sleep(2)            
            self.skt = None
            '''
            self.skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.skt.setblocking(True)
            server_address = ( self.ip , self.port)
            self.skt.connect(server_address)
            self.connected = True


            '''
            startCmd = self.cmds['start']
            sendRes = self.skt.sendall(startCmd)
            print(sendRes, self.getBytesStr(startCmd))
            '''

            recBuffers=[]
            status = 0
            dataSize = 0
            while 1>0 :
                recBytes = self.skt.recv(1)
                if len(recBytes)>0:
                    recBuffers.append(recBytes[0])
                    if status == 0 and recBytes[0]==0x68 :
                        status = 1
                    elif status == 1 :
                        status = 2
                        dataSize = 2 + recBytes[0]
                    elif status == 2:
                        if len(recBuffers)>=dataSize:
                            self.doOnRecPgk(recBuffers)
                            dataSiz=0
                            status = 0
                            recBuffers.clear()
                    #print(time.time(), self.getBytesStr(recBuffers))
                else:
                    print(recBytes)
                time.sleep(0.1)

        except Exception as er:
            print(er)
    def execRec(self):
        try:
            headFlag = 0
            recBuffers =[]
            dataSize =0
            print('start rec threading.')
            while self.isOpen():
                try:
                    recByte = self.skt.recv(1)
                    if len(recByte)>0:
                        print('rec:', self.getBytesStr(recByte))
                        recData = recByte[0]
                        if len(recByte)==1 and recData==0x68 and headFlag == 0 :
                            headFlag = 1
                            recBuffers.append(recByte[0])
                        elif len(recByte)==1 and headFlag==1 :
                            headFlag = 2
                            recBuffers.append(recByte[0])
                            dataSize = recData + 2
                        else :
                            recBuffers.append(recByte[0])
                            if( len(recBuffers) == dataSize ):
                                self.doOnRecPgk(recBuffers)
                        print(self.getBytesStr(recBuffers))
                except Exception as eer:
                    print(eer)
                    break

        except Exception as er:
            print(er)
        self.clientStatus = 0
    def execLoop(self):
        try:
            pass
        except Exception as er:
            print(er)
        self.clientStatus = 0
    def doOnRecPgk(self,recBuffers):
        try:
            print('onrecPgk',self.getBytesStr(recBuffers))

            if recBuffers[2]==0x43:
                cmds = self.cmds['testresp']
                print('s', self.getBytesStr(cmds))
                self.skt.send( cmds)
            elif len(recBuffers)==6 and (recBuffers[2] & 0x03 ) ==1 :
                print('s frame')
            elif len(recBuffers)==6 and (recBuffers[2] & 0x03 ) ==3 :
                print('u frame')
            else :
                print('i frame')
                snoL = recBuffers[4]
                snoH = recBuffers[5]
                snoL = snoL + 2
                if snoL>0xff :
                    snoL = snoL -1
                    snoH = snoH + 1
                    cmds = bytearray([0x68,0x04,0x01,0,snoL,snoH])
                    sendRes = self.skt.sendall(cmds)
                    print(sendRes , self.getBytesStr(cmds))
        except Exception as er:
            print(er)



client = TIce104Client()
client.ip = "192.168.8.10"
client.port = 2404
client.exec()
while 1>0:
    a = input('please input command')
    if a=='exit':
        break